using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using SimpleJSON;

[Serializable]
public class ServerHost
{
	public string host;
	public string port;
}

public class HttpClient : MonoBehaviour {

    public static HttpClient instance;

	public ServerHost productionServer;
	public ServerHost developmentServer;

	public static bool isInternetReachable
	{
		get {
			return Application.internetReachability != NetworkReachability.NotReachable;
		}
	}

	void Awake()
	{
		if( instance == null )
			instance = this;
	}

	void OnDestroy()
	{
		if (instance == this)
			instance = null;
	}

	string GetRequestAPI(string api)
	{
#if UNITY_EDITOR
		return "http://" + developmentServer.host + ":" + developmentServer.port + "/" + api;
#else
		return "http://" + productionServer.host + ":" + productionServer.port + "/" + api;
#endif
    }

    #region GET request
    public void Request(string api, Action<int, JSONNode> response)
	{
		if (Application.internetReachability == NetworkReachability.NotReachable)
		{
			if (response != null)
				response(ResultCode.NOT_CONNECT, null);
			return;
		}
		StartCoroutine(_Request(api, response));
	}

    IEnumerator _Request(string api, Action<int, JSONNode> response)
	{
		WWW www = new WWW(GetRequestAPI(api));

		while (!www.isDone && www.error == null)
		{
			yield return null;
		}

		if (www.error != null)
		{
            Debug.Log("Request Error. Url: " + www.url+","+ api + ", Error: " + www.error);
			if (response != null)
				response(ResultCode.HTTP_ERROR, null);
			yield break;
		}

		Debug.Log("Request response. Url: " + www.url+", "+ api + ", Response: " + www.text);
		if (response != null)
		{
			JSONNode json = JSON.Parse(www.text);
			response(json["code"].AsInt, json);
		}

		www.Dispose();
    }
    #endregion

    #region POST request
    public void RequestPOST(string api, Dictionary<string, object> parameters, Action<int, JSONNode> response)
    {
        if (Application.internetReachability == NetworkReachability.NotReachable)
        {
            if (response != null)
                response(ResultCode.NOT_CONNECT, null);
            return;
        }

        StartCoroutine(_RequestPOST(api, parameters, response));
    }

    IEnumerator _RequestPOST(string api, Dictionary<string, object> parameters, Action<int, JSONNode> response)
    {
        WWWForm form = new WWWForm();

        foreach (KeyValuePair<string, object> pair in parameters)
            form.AddField(pair.Key, pair.Value.ToString());

        WWW www = new WWW(GetRequestAPI(api), form);

		while (!www.isDone && www.error == null)
		{
			yield return null;
		}

        if (www.error != null)
        {
			Debug.LogError("Request Error. Url: " + api + ", Error: " + www.error);

			if (response != null)
				response(ResultCode.HTTP_ERROR, null);
            yield break;
        }

		Debug.Log("Request response. Url: " + api + ", Response: " + www.text);

        if (response != null)
        {
            JSONNode json = JSON.Parse(www.text);
            response(json["code"].AsInt, json);
        }

        www.Dispose();
    }

    public void RequestDataPOST(string api, Hashtable header, string body, Action<int, JSONNode> response)
    {
        if (Application.internetReachability == NetworkReachability.NotReachable)
        {
            if (response != null)
                response(ResultCode.NOT_CONNECT, null);
            return;
        }

        StartCoroutine(_RequestDataPOST(api, header, body, response));
    }
#if UNITY_WP8
	public static Dictionary<K,V> HashtableToDictionary<K,V> (Hashtable table)
	{
		Dictionary<K,V> dict = new Dictionary<K,V>();
		foreach(DictionaryEntry kvp in table)
			dict.Add((K)kvp.Key, (V)kvp.Value);
		return dict;
	}
#endif
    IEnumerator _RequestDataPOST(string api, Hashtable header, string body, Action<int, JSONNode> response)
    {
        UTF8Encoding encoding = new System.Text.UTF8Encoding();
#if UNITY_WP8
			WWW www = new WWW(GetRequestAPI(api), encoding.GetBytes(body),HashtableToDictionary<string, string>(header));
#else
			WWW www = new WWW(GetRequestAPI(api), encoding.GetBytes(body),header);
#endif
		while (!www.isDone && www.error == null)
		{
			yield return null;
		}

        if (www.error != null)
        {
            if (response != null)
                response(ResultCode.HTTP_ERROR, null);
            yield break;
        }

        Debug.Log(www.text);

        if (response != null)
        {
            JSONNode json = JSON.Parse(www.text);
            response(ResultCode.SUCCESS, json);
        }

        www.Dispose();
    }
    #endregion
}